package com.qujia.framework.interceptor;

import com.qujia.common.utils.uuid.UUID;
import com.qujia.framework.constant.GlobalConstant;
import com.qujia.framework.constant.ServiceContext;
import com.qujia.framework.constant.ServiceContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;


/**
 * @Auther: zph
 * @Date: 2023/11/28 16:13
 * @Description:
 */
@Configuration
public class GlobalContextInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射conrtoller中的方法，直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 如果是方法探测，直接通过
        if (HttpMethod.OPTIONS.name().equalsIgnoreCase(request.getMethod())) {
            //OPTIONS请求不拦截
            return true;
        }
        if (!"REQUEST".equals(request.getDispatcherType().name())) {
            //不是request类型目前不处理
            return true;
        }

        String requestId = request.getHeader(GlobalConstant.HEADER_KEY_REQUEST_ID);
        String tenantId = request.getHeader(GlobalConstant.HEADER_KEY_TENANT_ID);
        String instanceId = request.getHeader(GlobalConstant.HEADER_KEY_INSTANCE_ID);
        String applicationId = request.getHeader(GlobalConstant.HEADER_KEY_APPLICATION_ID);
        String userId = request.getHeader(GlobalConstant.HEADER_KEY_USER_ID);
        String loginName = request.getHeader(GlobalConstant.HEADER_KEY_LOGIN_NAME);

        ServiceContext serviceContext = ServiceContextHolder.getContext();
        serviceContext.setRequestId(StringUtils.isNoneBlank(requestId) ? requestId : UUID.fastUUID().toString());
        MDC.put(GlobalConstant.HEADER_KEY_REQUEST_ID, serviceContext.getRequestId());
        if (StringUtils.isNoneBlank(tenantId)) {
            serviceContext.setTenantId(tenantId);
        }
        if (StringUtils.isNoneBlank(instanceId)) {
            serviceContext.setInstanceId(instanceId);
        }
        if (StringUtils.isNoneBlank(applicationId)) {
            serviceContext.setApplicationId(applicationId);
        }
        if (StringUtils.isNoneBlank(userId)) {
            serviceContext.setUserId(userId);
        }
        if (StringUtils.isNoneBlank(loginName)) {
            serviceContext.setLoginName(loginName);
        }

        Enumeration<String> headerNames = request.getHeaderNames();
        String key;
        while (headerNames.hasMoreElements()) {
            key = headerNames.nextElement();
            if (key.startsWith(ServiceContext.EXT_KEY_PREFIX)) {
                String value = request.getHeader(key);
                if (StringUtils.isNoneBlank(value)) {
                    serviceContext.putExtValue(key, value);
                }
            }
        }

        ServiceContextHolder.set(serviceContext);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //移除上下文
        ServiceContextHolder.cleanUp();
        MDC.clear();
    }
}
